package com.xiaomitest;

import java.util.Arrays;
import java.util.Scanner;

public class TencentTwo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // n为总人数 各个小组人数之和（去重）
        int n = sc.nextInt();
        // 分组的个数
        int m = sc.nextInt();
        // 每个组的对应上级
        int[] parnet = new int[n + 1];
        // 存储每个元素的对应位置，减少元素查找时间

        for (int i = 0; i <= n; i++) {
            // 初始时，每个人的上级都是自己
            parnet[i] = i;

        }
        // 接下来对每一个小集合进行处理
        for (int i = 0; i < m; i++) {
            // 每个小集合的人数个数
            int x = sc.nextInt();
            int[] smallGroup = new int[x];
            for (int j = 0; j < x; j++) {
                smallGroup[j] = sc.nextInt();
            }
            // 集合中就一个元素，那么就不需要进行上级合并了
            if(x > 1){
                Arrays.sort(smallGroup);
                int top = smallGroup[0];
                for (int j = 0; j < x; j++) {
                    // 如果每一个元素没有上级的话，那么此时指定数组第一个元素就是其上级
                    int subParent = find(smallGroup[j],parnet);
                    if(subParent == smallGroup[j]){
                        parnet[smallGroup[j]] = top;
                    }
                    // 有上级，那么在查找的时候就更新了上级
                }
            }
        }

        int res = 0;
        for (int i = 0; i < n; i++) {
            if(find(i,parnet) == 0){
                res++;
            }
        }
        System.out.println(res);

    }

    // 寻找自己的上级
    private static int find(int element,int[] parent){
        while (element != parent[element]){
            // 找上级 同时进行路径压缩（上级的上级 变为自己的上级）
            parent[element] = parent[parent[element]];
            // 上级的上级 变为自己的上级（减少中间的上级）
            element = parent[element];
        }
        return element;
    }

}
